package com.enjoyor.soa.traffic.frame.configure;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

@Configuration
@ConfigurationProperties(prefix = "system.config")
public class SystemConfig {

	public static Map<String, String> properties = new HashMap<String, String>();
	//缓存属性键值
    private static Map<String,Properties> propertiesMap = new HashMap<String,Properties>();
    
	private static Properties defaultProp = null;
	
	public Map<String, String> getProperties(){
		return properties;
	}
	
	public void setProperties(Map<String, String> properties){
		this.properties = properties;
	}
	
	public static String getProperty(String key){
		if(null != properties){
			if(properties.containsKey(key)){
				return properties.get(key);
			}else{
				return "";
			}
		}
		return "";
	}
	
	/**
     * 获取默认的属性值，resources.xml、resources.properties、configuration.xml、configuration.properties
     * @param key 键
     * @return 属性值
     */
    public static String getDefaultProperties(String key){
    	return getDefaultProperties(key,null);
    }
    
    /**
     * 获取默认的属性值
     * @param key 键
     * @param defaultValue 属性的默认值
     * @return 属性值
     */
    public static String getDefaultProperties(String key,String defaultValue){
    	return getProperties(null).getProperty(key,defaultValue);
    }
	
	/**
     * 获取properties键值
     * 
     * @param name properties名称，null时获取默认的属性键值
     * @return properties键值
     */
    public static Properties getProperties(String name){
    	if(name==null){
    		if(defaultProp==null){
    			defaultProp=new Properties();
    			loadProp(defaultProp,"resources.xml","xml");
    			loadProp(defaultProp,"resources.properties","props");
    			loadProp(defaultProp,"configuration.xml","xml");
    			loadProp(defaultProp,"application-dev.properties","props");
    		}
    		return defaultProp;
    	}
    	if(propertiesMap.get(name)==null){
    		Properties props=new Properties();
			loadProp(props,name+".xml","xml");
			loadProp(props,name+".properties","props");
			propertiesMap.put(name, props);
        }
        return propertiesMap.get(name);
    }
    
    /**
     * 获取properties值
     * 
     * @param name properties名称
     * @param key properties键
     * @return properties值
     */
    public static String getProperties(String name, String key){
    	return getProperties(name,key,null);
    }
    /**
     * 获取properties值
     * @param name properties名称
     * @param key properties键
     * @param defaultValue 默认值
     * @return
     */
    public static String getProperties(String name, String key, String defaultValue){
    	return getProperties(name).getProperty(key,defaultValue);
    }

    /**
     * 根据.properties配置new一个Bean
     * @param beanType Bean类型
     * @param propName properties名称
     * @param pref properties键值前缀
     * @return
     */
    public static <T> T newBean(Class<T> beanType,String pref){
    	return newBean(beanType,null,pref);
    }
    public static <T> T newBean(Class<T> beanType,String propName,String pref){
    	T o=null;
		try {
			o = beanType.newInstance();
	    	for(Field field : beanType.getDeclaredFields()){
	    		try {
					String val = getProperties(propName).getProperty(pref+"."+field.getName());
					if(val!=null){
						field.setAccessible(true);
		        		field.set(o, castTo(val,field.getType()));
					}
	    		} catch (Throwable e) { }
	    	}
		} catch (Throwable e) { }
    	return o;
    }
    

    static void loadProp(Properties prop,String file,String fileType){
    	try{
			InputStream in = SystemConfig.class.getResourceAsStream(file); 
			if(in==null) in = new ClassPathResource(file).getInputStream();
			if(in!=null){
				if(fileType.equals("xml")){
					prop.loadFromXML(in);
				}else if(fileType.equals("props")){					
					prop.load(in);
				}
			}
		}catch(Throwable e){}
    }
    
    static SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    static SimpleDateFormat sdf2= new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    static SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd");
    static SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy/MM/dd");
    /**
     * 将val转换为类型toType的数据
     * @param val
     * @param toType
     * @return
     */
    public static <T> T castTo(String val,Class<T> toType){
    	Object ret = null;
    	try{
    		if(val!=null&&!"".equals(val)){
		    	if(toType.equals(String.class)){
		    		ret = val;
				}else if(toType.equals(Integer.class)||toType.equals(int.class)){
					ret = Integer.parseInt(val);
				}else if(toType.equals(Long.class)||toType.equals(long.class)){
					ret = Long.parseLong(val);
				}else if(toType.equals(Short.class)||toType.equals(short.class)){
					ret = Short.parseShort(val);
				}else if(toType.equals(Byte.class)||toType.equals(byte.class)){
					ret = Byte.parseByte(val);
				}else if(toType.equals(Double.class)||toType.equals(double.class)){
					ret = Double.parseDouble(val);
				}else if(toType.equals(Float.class)||toType.equals(float.class)){
					ret = Float.parseFloat(val);
				}else if(toType.equals(Boolean.class)||toType.equals(boolean.class)){
					ret = Boolean.parseBoolean(val);
				}else if(toType.equals(Date.class)){
					try{ret = sdf1.parse(val);}catch(Throwable e1){
					try{ret = sdf2.parse(val);}catch(Throwable e2){
					try{ret = sdf3.parse(val);}catch(Throwable e3){
					try{ret = sdf4.parse(val);}catch(Throwable e4){
					}}}}
				}
    		}
    	}catch(Throwable ex){}
    	return (T) ret;
    }
}
